package com.spj.shiro;

import com.spj.entity.Perm;
import com.spj.entity.Role;
import com.spj.entity.User;
import com.spj.service.impl.PermServiceDaoImpl;
import com.spj.service.impl.RoleServiceDaoImpl;
import com.spj.service.impl.UserServiceDaoImpl;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author :spj
 * @Date:2022/4/14
 * @description:
 */
@Configuration
public class MyRealm extends AuthorizingRealm {
    @Autowired
    UserServiceDaoImpl userService;
    @Autowired
    RoleServiceDaoImpl roleService;
    @Autowired
    PermServiceDaoImpl permService;
    @Autowired
    RedisTemplate redisTemplate;
    @Override
    public boolean supports(AuthenticationToken token) {
//        这里是shiro底层的问题，我们要手动重写底层的判断逻辑
        return token instanceof MyJWT;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String token = principals.getPrimaryPrincipal() + "";
        String username = JwtUtil.getSubject(token);
        //检验后
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

        //添加角色
        User user;
        Role role;
        if (redisTemplate.opsForValue().get("Role")==null){
            user = userService.findUserByName(username);
            role = roleService.findRoleByUserRoleId(user.getRole_id());
            redisTemplate.opsForValue().set("Role",role);
        }else {
            role=(Role)redisTemplate.opsForValue().get("Role");
            System.out.println("缓存角色");
        }
        simpleAuthorizationInfo.addRole(role.getName());
        //添加权限
        Set<String> set;
        if (redisTemplate.opsForValue().get("perms")==null){
            user = userService.findUserByName(username);
            List<Perm> perms = permService.findPermsByUserRoleId(user.getRole_id());
            set= new HashSet<>();
            for (Perm perm : perms) {
                set.add(perm.getCode());
            }
            redisTemplate.opsForValue().set("perms",set);
        }else{
            set=(Set)redisTemplate.opsForValue().get("perms");
            System.out.println("缓存权限");
        }
        simpleAuthorizationInfo.setStringPermissions(set);
        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken jwtToken) throws AuthenticationException {
        String token = jwtToken.getPrincipal() + "";
        String username = JwtUtil.getSubject(token);
        User user = userService.findUserByName(username);
        String password = user.getPassword();
        JwtUtil.verify(token, username, password);
        return new SimpleAuthenticationInfo(token, token, "myRealm");
    }
}
